// 实现这个项目的构建任务
const { src, dest, watch, parallel, series } = require("gulp");
const del = require("del");
const browserSync = require("browser-sync");
const LoadGulpPlugins = require("gulp-load-plugins");

const plugins = LoadGulpPlugins();
const bs = browserSync.create(); // 创建 browser-sync 实例

const data = {
  menus: [
    {
      name: "Home",
      icon: "aperture",
      link: "index.html",
    },
    {
      name: "Features",
      link: "features.html",
    },
    {
      name: "About",
      link: "about.html",
    },
    {
      name: "Contact",
      link: "#",
      children: [
        {
          name: "Twitter",
          link: "https://twitter.com/w_zce",
        },
        {
          name: "About",
          link: "https://weibo.com/zceme",
        },
        {
          name: "divider",
        },
        {
          name: "About",
          link: "https://github.com/zce",
        },
      ],
    },
  ],
  pkg: require("./package.json"),
  date: new Date(),
};

const style = () => {
  return src("src/assets/styles/*.scss")
    .pipe(plugins.sass({ outputStyle: "expanded" }))
    .pipe(dest("temp"))
    .pipe(bs.reload({ stream: true }));
};

const script = () => {
  return src("src/assets/scripts/*.js", { base: "src" })
    .pipe(
      plugins.babel({
        presets: [require("@babel/preset-env")],
      })
    )
    .pipe(dest("temp"))
    .pipe(bs.reload({ stream: true }));
};

const page = () => {
  return src("src/*.html", { base: "src" })
    .pipe(plugins.swig({ data, defaults: { cache: false } }))
    .pipe(dest("temp"))
    .pipe(bs.reload({ stream: true }));
};

const image = () => {
  return src("src/assets/images/**", { base: "src" })
    .pipe(plugins.imagemin())
    .pipe(dest("dist"));
};

const font = () => {
  return src("src/assets/fonts/**", { base: "src" })
    .pipe(plugins.imagemin())
    .pipe(dest("dist"));
};

const extra = () => {
  return src("public/**", { base: "public" }).pipe(dest("dist"));
};

// 删除目录
const clean = () => {
  return del(["dist", "temp"]);
};

const serve = () => {
  /** @name 监听经常改变的文件 */
  watch("src/assets/styles/*.scss", style);
  watch("src/assets/scripts/*.js", script);
  watch("src/*.html", page);

  /** @name 监听文件变化，刷新浏览器 */
  watch(["src/assets/image/**", "src/assets/fonts/**", "public/**"], bs.reload);

  bs.init({
    notify: false,
    port: 9090,
    server: {
      baseDir: ["temp", "src", "public"],
      routes: {
        "/node_modules": "node_modules", // 文件的中的地址为 /node_modules 映射到依赖包node_modules中
      },
    },
  });
};

/** @name 资源压缩 */
const useref = () => {
  // searchPath 搜索范围 temp目录 - 本地目录
  return src("temp/*.html", { base: "temp" })
    .pipe(plugins.useref({ searchPath: ["temp", "."] }))
    .pipe(plugins.if(/\.js$/, plugins.uglify()))
    .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
    .pipe(
      plugins.if(
        /\.html$/,
        plugins.htmlmin({
          collapseWhitespace: true,
          minifyCSS: true,
          minifyJS: true,
        })
      )
    )
    .pipe(dest("dist"));
};

const lint = () => {
  return src("src/**/*.js", { base: "temp" })
    .pipe(
      plugins.eslint({
        parserOptions: {
          ecmaVersion: 6,
        },
        rules: {
          camelcase: 1,
          "comma-dangle": 2,
          quotes: 0,
        },
        env: {
          es6: true,
          jquery: true,
          browser: true,
        }
      })
    )
    .pipe(plugins.eslint.format())
    .pipe(
      plugins.eslint.result((result) => {
        // Called for each ESLint result.
        console.log(`ESLint result: ${result.filePath}`);
        console.log(`# Messages: ${result.messages.length}`);
        console.log(`# Warnings: ${result.warningCount}`);
        console.log(`# Errors: ${result.errorCount}`);
      })
    );
};

const compile = parallel(style, script, page);

const build = series(
  clean,
  parallel(series(compile, useref), image, font, extra)
);

const start = series(compile, serve);

module.exports = {
  build,
  start,
  clean,
  lint,
};
